package fr.ul.ade.secunde.sync;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

import android.app.Service;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.IBinder;
import android.provider.BaseColumns;
import android.util.Log;
import fr.ul.ade.R;
import fr.ul.ade.secunde.database.AdeWebContract;
import fr.ul.ade.secunde.util.AdeWebFactory;
import fr.ul.ade.secunde.util.Bundles;

/**
 * Service responsable des synchronisations des emplois du temps. Le service
 * gère les synchronisations automatiques et manuelles. Les synchronisations se
 * font sur des threads séparés.
 * 
 * @author Michaël Schnell
 * @since Jul 28, 2013
 * 
 * @version 1.3
 */
public class AdeWebService
		extends Service {

	/**
	 * Gestionnaire pour les threads hébergeant les sychronisations.
	 */
	protected ScheduledExecutorService scheduler;

	@Override
	public IBinder onBind(Intent intent) {
		return null; /* No bind possible. */
	}

	@Override
	public void onCreate() {
		super.onCreate();
		this.scheduler = Executors.newScheduledThreadPool(this.getResources()
				.getInteger(R.integer.number_concurrent_updates));
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (intent != null) {
			Resources res = this.getResources();
			String action = intent.getAction();
			if (action.equals(res
					.getString(R.string.intent_action_update_schedule))) {
				this.updateSchedule(intent.getLongExtra(Bundles.SCHEDULE_ID, 0));
			} else if (action.equals(res
					.getString(R.string.intent_action_get_projects))) {
				this.updateProjects();
			}// if
		}// if
		return super.onStartCommand(intent, flags, startId);
	}

	private void updateSchedule(final long scheduleId) {
		// TODO Extraire dans une classe à part
		this.scheduler.execute(new Runnable() {
			@Override
			public void run() {
				Log.d("[updateSchedule]", "Id: " + scheduleId);

				try {
					AdeWebInterface adeWebInterface = AdeWebFactory
							.establishConnection(AdeWebService.this);
					// Chargement de l'emploi du temps (-> projet ADE)
					final Cursor schedule = AdeWebService.this
							.getContentResolver()
							.query(AdeWebContract.Schedule.buildUri(scheduleId),
									ScheduleQuery.PROJECTION,
									null,
									null,
									AdeWebContract.Schedule.SORT_BY_ADE_PROJECT_ID);
					// Lancement de la mise à jour
					if (schedule.moveToFirst()) {
						adeWebInterface.setProject(schedule
								.getLong(ScheduleQuery.SCHEDULE_ADE_PROJECT_ID));

						AdeWebService.this.scheduler
								.execute(new ScheduleUpdateRunnable(scheduleId,
										adeWebInterface, AdeWebService.this));
					}
					// Libération du curseur
					schedule.close();
				} catch (Exception e) {
					Log.e("[updateSchedule]", "Update failed !", e);
				}
				// catch (IOException ioe) {
				// // FIXME Log and report exception !
				// } catch (NotFoundException nfe) {
				// // TODO: handle exception
				// } catch (XmlPullParserException xppe) {
				// // FIXME Log and report exception !
				// }
			}
		});
	}

	private void updateAll() {

	}

	private void updateProjects() {
		this.scheduler.execute(new ProjectUpdateRunnable(this));
	}

	// --------------------------------------------------------
	//
	// Données chargées
	//
	// --------------------------------------------------------

	protected interface ScheduleQuery {
		final String[] PROJECTION = { BaseColumns._ID,
				AdeWebContract.Schedule.SCHEDULE_ADE_PROJECT_ID };

		final int _ID = 0;
		final int SCHEDULE_ADE_PROJECT_ID = 1;
	}

}// class AdeWebService